package com.epam.training;

import java.math.BigDecimal;
import java.security.Principal;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.epam.training.service.bonus.BonusService;
import com.epam.training.service.bookingitem.BookingItemService;
import com.epam.training.service.car.CarService;
import com.epam.training.service.insurance.InsuranceService;
import com.epam.training.service.paymant.PaymantService;
import com.epam.training.service.penalty.PenaltyService;
import com.epam.training.service.user.UserService;
import com.epam.training.domain.Bonus;
import com.epam.training.domain.BookingItem;
import com.epam.training.domain.Car;
import com.epam.training.domain.Customer;
import com.epam.training.domain.Insurance;
import com.epam.training.domain.Paymant;
import com.epam.training.domain.Penalty;
import com.epam.training.formvalidate.BookingItemForm;

/**
 * @author Bogdan
 *
 */
@Controller
public class CustomerPageController {
	public final static String HOME_JSP = "customer";

	public final static String HOME_PAGE = "/customer";

	private final UserService userService;

	private final BookingItemService bookingService;

	private final PaymantService paymantService;

	private final BonusService bonusService;

	private final PenaltyService penaltyService;

	private final InsuranceService insuranceService;

	private final CarService carService;

	@Autowired
	public CustomerPageController(UserService userService,
			BookingItemService bookingService, PaymantService paymantService,
			BonusService bonusService, PenaltyService penaltyService,
			InsuranceService insuranceService, CarService carService) {
		this.userService = userService;
		this.bookingService = bookingService;
		this.paymantService = paymantService;
		this.bonusService = bonusService;
		this.penaltyService = penaltyService;
		this.insuranceService = insuranceService;
		this.carService = carService;
	}

	/**
	 * 
	 * 
	 * @param model
	 * @param principal
	 * @return
	 */
	@RequestMapping(value = { "/customer", "/customer/show" })
	// Principle contain current session user login
	private String homePage(@RequestParam(required = false) String message,
			Model model, Principal principal) {
		List<BookingItem> booking = bookingService
				.getAllBookingItemForUser(principal.getName());

		if (message != null) {
			model.addAttribute("message", message);
		}

		model.addAttribute("bookingItemList", booking);

		return HOME_JSP;

	}

	@RequestMapping(value = "/customer/show/booking", method = RequestMethod.GET)
	public String showBooking() {
		return "redirect:/customer";
	}

	@RequestMapping(value = "/customer/show/car", method = RequestMethod.GET)
	private String showAllCar() {
		return "redirect:/customer/show/car/pages/1";
	}

	@RequestMapping(value = "/customer/show/car/pages/{pageNumber}", method = RequestMethod.GET)
	private String showAllCar(@PathVariable Integer pageNumber, Model model) {
		Page<Car> page = carService.getAllCar(pageNumber);

		model.addAttribute("carList", page);
		setPageableAtribute(page, model);

		return "customerView/fleet";
	}

	private <T> void setPageableAtribute(Page<T> page, Model model) {
		int current = page.getNumber() + 1;
		int begin = Math.max(1, current - 5);
		int end = Math.min(begin + 10, page.getTotalPages());

		model.addAttribute("beginIndex", begin);
		model.addAttribute("endIndex", end);
		model.addAttribute("currentIndex", current);
	}

	@RequestMapping(value = "/customer/pay/{bookingItemId}", method = RequestMethod.GET)
	private String showBookingItem(@PathVariable Integer bookingItemId,
			Model model) {
		BookingItem bookingItem = bookingService.getById(bookingItemId);

		BigDecimal price = paymantService.calculatePrice(bookingItem
				.getDateOfReturn(), bookingItem.getDateOfIssue(), bookingItem
				.getCar().getPrice(), bookingItem.getInsurance().getPrice());

		model.addAttribute("bookingItem", bookingItem);
		model.addAttribute("bookingItemPrice", price);

		return "customerView/pay";
	}

	@RequestMapping(value = "/customer/show/paymant/{paymantId}", method = RequestMethod.GET)
	private String showPaymant(@PathVariable Integer paymantId, Model model) {
		Paymant paymant = paymantService.getById(paymantId);
		model.addAttribute("paymant", paymant);

		return "customerView/ShowPaymant";
	}

	@RequestMapping(value = "/customer/show/bonus/{bonusId}", method = RequestMethod.GET)
	private String showBonus(@PathVariable Integer bonusId, Model model) {
		Bonus bonus = bonusService.getById(bonusId);
		model.addAttribute("bonus", bonus);

		return "customerView/ShowBonus";
	}

	@RequestMapping(value = "/customer/show/penalty/{penaltyId}", method = RequestMethod.GET)
	private String showPenalty(@PathVariable Integer penaltyId, Model model) {
		Penalty penalty = penaltyService.getById(penaltyId);
		model.addAttribute("penalty", penalty);

		return "customerView/ShowPenalty";
	}

	@RequestMapping(value = "/customer/show/insurance/{insuranceId}", method = RequestMethod.GET)
	private String showInsurance(@PathVariable Integer insuranceId, Model model) {
		Insurance insurance = insuranceService.getById(insuranceId);
		model.addAttribute("insurance", insurance);

		return "customerView/ShowInsurance";
	}

	@RequestMapping(value = "/customer/show/car/{carId}", method = RequestMethod.GET)
	private String showCar(@PathVariable Integer carId, Model model) {
		Car car = carService.getById(carId);
		model.addAttribute("car", car);

		return "customerView/ShowCar";
	}

	@RequestMapping(value = "/customer/newBooking")
	private String newBooking(
			@RequestParam(value = "carId", required = false) Integer carId,
			Model model) {
		if (carId != null) {
			Car car = carService.getById(carId);
			model.addAttribute("carId", car.getCarId());
		}

		List<Car> carList = carService.getAllCar();
		List<Insurance> insuranceList = insuranceService.getAllInsurance();

		model.addAttribute("carList", carList);
		model.addAttribute("insuranceList", insuranceList);
		
		model.addAttribute("bookingItemForm", new BookingItemForm());

		return "customerView/NewBooking";
	}

	@RequestMapping(value = "/customer/show/account")
	private String accountPage(Principal principal, Model model) {
		Customer customer = userService
				.findCustomerByLogin(principal.getName());

		model.addAttribute("customer", customer);
		return "customerView/account";
	}
}
